//
//  EAGLView.h
//  ___PROJECTNAME___
//
//  Created by ___FULLUSERNAME___ on ___DATE___.
//  Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved.
//

//
//  EAGLView.h
//  template
//
//  Created by SIO2 Interactive on 8/22/08.
//  Copyright SIO2 Interactive 2008. All rights reserved.
//

//File modified by Goffredo Marocchi (this is not the original SIO2 provided file,
//sio2 and its creator ROm are not responsible for the content of this file as it is now

//Google code

#import <UIKit/UIKit.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>

#import "sio2.h"
#import "ShadowMatrix.h"
#import "Projector.h"

#import "ESRenderer.h"

// This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass.
// The view content is basically an EAGL surface you render your OpenGL scene into.
// Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
@interface EAGLView : UIView
{    
@private
    id <ESRenderer> renderer;
	
	id displayLink;
	NSTimer *animationTimer;
	
	BOOL displayLinkSupported;
	BOOL isAnimating;
	BOOL isSimulator;
	
	//TODO: implement a state manager overseeing camera and other elements
	BOOL updateCameraProjectionMatrix;
	BOOL updateCameraModelViewMatrix;
	//
	
	NSInteger animationFrameInterval;
	ShadowMatrix* shadowMatrix;
	Projector* sceneProjector;
	
	SIO2object* objShadowReceiver[MAX_SHADOW_RECEIVERS];
	
	vec3 temp_camera_loc;
	vec3 temp_camera_target;
}

@property (nonatomic) NSInteger animationFrameInterval;
@property (copy) ShadowMatrix* shadowMatrix;
@property (copy) Projector* sceneProjector;
@property (nonatomic) BOOL updateCameraProjectionMatrix;
@property (nonatomic) BOOL updateCameraModelViewMatrix;

- (void)startAnimation;
- (void)stopAnimation;
- (void)drawView:(id)sender;

-(CFTimeInterval) getCADLTimeStamp;

-(void) setObjShadowReceiver:(SIO2object **)obj;

/////////////////////////////////////////////////////////

-(int)  getTriangleCountFromObject:(SIO2object*)obj;
-(void) getTriangleList:(vec3*)trianglePtr fromObject:(SIO2object*)obj;
-(void) calculatePlaneNormal:(SIO2object *)plane withCam:(const SIO2camera*)cam withNormal:(vec3*)normal;
-(void) calculateTriangleNormal:(vec3*)normal v0:(const vec3*)v0 v1:(const vec3*)v1 v2:(const vec3*)v2;
-(void) renderSIO2ObjectNormal:(char*) objString withSIO2:(SIO2*)sio2;
-(void) drawNormal:(vec3*)normal ofPoint:(vec3*)p;
-(vec3) travelAlongNormal:(vec3*)normal fromPoint:(vec3*)p1 distance:(float)dist;
-(void) drawLineFrom:(vec3 *)fromPoint to:(vec3 *)toPoint withColor:(GLubyte*)color; //DEBUG function
-(void) matPerspective:(float*)m withFov:(float)fovYdeg aspectRatio:(float)aRatio zNear:(float)zN zFar:(float)zF portrait:(BOOL)rot 
				zRangeInverted:(BOOL)inverted;
-(void) matPerspectiveFPz:(float*)m withFov:(float)fovYdeg aspectRatio:(float)aRatio zNear:(float)zN portrait:(BOOL)rot 
				   zRangeInverted:(BOOL)inverted;
-(void) matLookAt:(MATRIX*)m eye:(vec3*)_e vTarget:(vec3*)_c upVector:(vec3*)_u;
-(void) matLookAt:(MATRIX*)m eye:(vec3*)_e vDir:(vec3*)_d upVector:(vec3*)_u;
-(void) vec3LerpVec1:(vec3*)v1 vec2:(vec3*)v2 withCoeff:(float)s intoVec:(vec3*)vOut;

-(void) setupLighting;
-(void) loadSIO2Camera:(const char*)camera;

-(void) cameraUpdate:(SIO2camera*) _SIO2camera;
-(void) renderCameraProjectionMatrix:(MATRIX*)mProjection;
-(void) renderCameraModelViewMatrix:(MATRIX*)mView enableLandscape:(BOOL)landscape;
-(void) drawCameraFrustum:(SIO2camera*)cam aspectRatio:(float)aspect;

-(void) enableClipPlane:(int)clipPlaneIndex withPlaneNormal:(vec3*)normal withOffset:(float)offset;
-(void) disableClipPlane:(int)clipPlaneIndex;

-(void) renderAllObjects;
-(void) renderShadowReceiverObject:(SIO2object*)obj;
-(void) renderShadowCasters;
-(void) renderLights;
-(void) renderTransparentObjects;
-(void) renderIPO;

- (CGSize)frame_size;

-(id) getDelegate;

-(void) loadImageSetTexture:(NSString*)image withId:(NSString*)texId;

/////////////////////////////////////////////////////////

+(BOOL) isSIO2ObjectName:(NSString*)str InSIO2ObjectArray:(SIO2object**)obj ofSize:(int)size;

@end
